package com.ruoyi.coal.modules.publicAPI.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.util.FileUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;

import com.ruoyi.coal.modules.coalpile.domain.RadarEntity;
import com.ruoyi.coal.modules.coalpile.mapper.CoalYardInfoDao;
import com.ruoyi.coal.modules.coalpile.mapper.CutUpDao;
import com.ruoyi.coal.modules.coalpile.mapper.RadarDao;
import com.ruoyi.coal.modules.publicAPI.service.StartRadarService;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

@Service("StartRadarService")
@DataSource(value = DataSourceType.SLAVE)
public class StartRadarServiceImpl extends ServiceImpl<RadarDao, RadarEntity> implements StartRadarService {
    @Value("${pythonAPI.sleepTime}")
    private Long sleepTime;

    @Value("${pythonAPI.ip}")
    private String pythonIp;

    @Resource
    private CoalYardInfoDao coalYardInfoDao;

    @Resource
    private RadarDao radarDao;

    @Resource
    private CutUpDao cutUpDao;

    public Map<String, Object> startRadar(Integer coalYardId, String uuid) throws InterruptedException {
        int coalYardNum = this.coalYardInfoDao.getCoalYardId().size();
        int[] ports = new int[coalYardNum];
        for (int i = 0; i < coalYardNum; i++)
            ports[i] = 8000 + i;
        int port = ports[(coalYardId.intValue() - 1) % coalYardNum];
        String url = "http://" + this.pythonIp + ":" + port + "/coal/startRadar";
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        LinkedMultiValueMap linkedMultiValueMap = new LinkedMultiValueMap();
        linkedMultiValueMap.add("coalYardId", coalYardId);
        linkedMultiValueMap.add("uuid", uuid);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, Object>> param = new HttpEntity(linkedMultiValueMap, (MultiValueMap)headers);
        TimeUnit.SECONDS.sleep(((coalYardId.intValue() - 1) % coalYardNum) * this.sleepTime.longValue());
        ResponseEntity<String> response = restTemplate.postForEntity(url, param, String.class, new Object[0]);
        String body = (String)response.getBody();
        return (Map<String, Object>)JSON.parseObject(body, Map.class);
    }

    public void startRadars(Map.Entry<Integer, Integer> entry) throws InterruptedException {
        int port = 8000 + ((Integer)entry.getKey()).intValue();
        String url = "http://" + this.pythonIp + ":" + port + "/coal/startRadarTimed";
        System.out.println("煤场id为"+ entry.getValue() + "启动的端口号:" + port);
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        LinkedMultiValueMap linkedMultiValueMap = new LinkedMultiValueMap();
        linkedMultiValueMap.add("coalYardId", entry.getValue());
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, Object>> param = new HttpEntity(linkedMultiValueMap, (MultiValueMap)headers);
        TimeUnit.SECONDS.sleep(((Integer)entry.getKey()).intValue() * this.sleepTime.longValue());
        System.out.println(DateUtil.now() + " 启动的端口号，——键盘点：" + port);
        try {
            CompletableFuture.runAsync(() -> restTemplate.postForEntity(url, param, String.class, new Object[0]));
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public Map<String, Object> startRadarTimed(Integer coalYardId) throws InterruptedException {
        int coalYardNum = this.coalYardInfoDao.getCoalYardId().size();
        int[] ports = new int[coalYardNum];
        for (int i = 0; i < coalYardNum; i++)
            ports[i] = 8000 + i;
        int port = ports[(coalYardId.intValue() - 1) % coalYardNum];
        System.out.println(coalYardId + "启动的端口号：" + port);
                String url = "http://" + this.pythonIp + ":" + port + "/coal/startRadarTimed";
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        LinkedMultiValueMap linkedMultiValueMap = new LinkedMultiValueMap();
        linkedMultiValueMap.add("coalYardId", coalYardId);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, Object>> param = new HttpEntity(linkedMultiValueMap, (MultiValueMap)headers);
        TimeUnit.SECONDS.sleep(((coalYardId.intValue() - 1) % coalYardNum) * this.sleepTime.longValue());
        System.out.println(DateUtil.now() + "启动的端口号，定时任务：" + port);
                ResponseEntity<String> response = restTemplate.postForEntity(url, param, String.class, new Object[0]);
        String body = (String)response.getBody();
        return (Map<String, Object>)JSON.parseObject(body, Map.class);
    }

    public Map<String, Object> radarCheck(String port, String radarIp, String computerIp) {
        String url = "http://" + this.pythonIp + ":8000/coal/checkradar";
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        LinkedMultiValueMap linkedMultiValueMap = new LinkedMultiValueMap();
        linkedMultiValueMap.add("port", port);
        linkedMultiValueMap.add("ip1", radarIp);
        linkedMultiValueMap.add("ip2", computerIp);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, Object>> param = new HttpEntity(linkedMultiValueMap, (MultiValueMap)headers);
        ResponseEntity<String> response = restTemplate.postForEntity(url, param, String.class, new Object[0]);
        String body = (String)response.getBody();
        return (Map<String, Object>)JSON.parseObject(body, Map.class);
    }

    public Map<String, Object> checkSerial(String port) {
        String url = "http://" + this.pythonIp + ":8000/coal/checkserial";
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        LinkedMultiValueMap linkedMultiValueMap = new LinkedMultiValueMap();
        linkedMultiValueMap.add("port", port);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, Object>> param = new HttpEntity(linkedMultiValueMap, (MultiValueMap)headers);
        ResponseEntity<String> response = restTemplate.postForEntity(url, param, String.class, new Object[0]);
        String body = (String)response.getBody();
        return (Map<String, Object>)JSON.parseObject(body, Map.class);
    }

    public Map<String, Object> getPcdAndPoint(String filePath) {
        String url = "http://" + this.pythonIp + ":8000/coal/getmaxmin";
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        LinkedMultiValueMap linkedMultiValueMap = new LinkedMultiValueMap();
        linkedMultiValueMap.add("ascfilename", filePath);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, Object>> param = new HttpEntity(linkedMultiValueMap, (MultiValueMap)headers);
        ResponseEntity<String> response = restTemplate.postForEntity(url, param, String.class, new Object[0]);
        String body = (String)response.getBody();
        return (Map<String, Object>)JSON.parseObject(body, Map.class);
    }

    public Map<String, Object> importCloud(Integer coalYardId, String filePath) {
        String url = "http://" + this.pythonIp + ":8000/coal/filemeasure";
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        LinkedMultiValueMap linkedMultiValueMap = new LinkedMultiValueMap();
        linkedMultiValueMap.add("coal_yard_id", coalYardId);
        linkedMultiValueMap.add("ascfilename", filePath);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, Object>> param = new HttpEntity(linkedMultiValueMap, (MultiValueMap)headers);
        ResponseEntity<String> response = restTemplate.postForEntity(url, param, String.class, new Object[0]);
        String body = (String)response.getBody();
        return (Map<String, Object>)JSON.parseObject(body, Map.class);
    }

    public void cutUpAndMeasure(Integer coalYardId) {
        int coalYardNum = this.coalYardInfoDao.getCoalYardId().size();
        int[] ports = new int[coalYardNum];
        for (int i = 0; i < coalYardNum; i++)
            ports[i] = 8000 + i;
        int port = ports[(coalYardId.intValue() - 1) % coalYardNum];
        System.out.println(coalYardId + "二次分割启动端口号" + port);
                String url = "http://" + this.pythonIp + ":" + port + "/coal/cutUpAndMeasure";
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        LinkedMultiValueMap linkedMultiValueMap = new LinkedMultiValueMap();
        List<RadarEntity> radarEntityList = this.radarDao.selectList((Wrapper)(new QueryWrapper()).eq("coal_yard_id", coalYardId));
        List<String> ascFilesList = new ArrayList<>();
        for (RadarEntity radarEntity : radarEntityList)
            ascFilesList.add(coalYardId + "-" + radarEntity.getIp1() + "-filename.asc");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("coalYardId", coalYardId);
        jsonObject.put("ascFilesList", ascFilesList);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        ResponseEntity<String> response = restTemplate.postForEntity(url, jsonObject, String.class, new Object[0]);
    }

    public JSONObject sendCommand(String command, Integer coalYardId) {
        int coalYardNum = this.coalYardInfoDao.getCoalYardId().size();
        int[] ports = new int[coalYardNum];
        for (int i = 0; i < coalYardNum; i++)
            ports[i] = 8000 + i;
        int port = ports[(coalYardId.intValue() - 1) % coalYardNum];
        String url = "http://" + this.pythonIp + ":" + port + "/coal/sendCommand";
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        List<String> radarPtzComs = new ArrayList<>();
//        List coal_yard_id = this.radarDao.selectList((Wrapper) (new QueryWrapper()).eq("coal_yard_id", coalYardId));
        for (RadarEntity radarEntity : (List<RadarEntity>)this.radarDao.selectList((Wrapper)(new QueryWrapper()).eq("coal_yard_id", coalYardId)))
            radarPtzComs.add(radarEntity.getPtzCom());
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("radarPtzComs", radarPtzComs);
        jsonObject.put("command", command);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        ResponseEntity<String> response = restTemplate.postForEntity(url, jsonObject, String.class, new Object[0]);
        return JSONObject.parseObject((String)response.getBody());
    }

    public void startSocket() {
        (new Thread(() -> {
            int serverPort = 5567;
            String fileName = "socketFile.txt";
            try {
                ServerSocket serverSocket = new ServerSocket(serverPort);
                System.out.println("Server started, listening on port " + serverPort);
                while (true) {
                    Socket clientSocket = serverSocket.accept();
                    System.out.println("Client connected: " + clientSocket.getInetAddress());
                    FileOutputStream fileOutputStream = new FileOutputStream(fileName);
                    InputStream in = clientSocket.getInputStream();
                    byte[] buffer = new byte[1024];
                    int bytesRead;
                    while ((bytesRead = in.read(buffer)) != -1)
                        fileOutputStream.write(buffer, 0, bytesRead);
                    fileOutputStream.close();
                    in.close();
                    clientSocket.close();
                    File uploadedFile = new File(fileName);
                    if (uploadedFile.length() > 0L) {
                        System.out.println("Data received and saved to " + fileName);
                        MultipartFile multipartFile = getMultipartFile(uploadedFile);
                        String str = DateUtil.format(new Date(), "yyyy-MM-dd-HH-mm-ss");
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                return;
            }
        })).start();
    }

    public static MultipartFile getMultipartFile(File file) {
        DiskFileItem item = new DiskFileItem("file", "multipart/form-data", true, file.getName(), (int)file.length(), file.getParentFile());
        try {
            OutputStream os = item.getOutputStream();
            os.write(FileUtils.readFileToByteArray(file));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return (MultipartFile)new CommonsMultipartFile((FileItem)item);
    }
}

